package com.xbongbong.paas.help;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.ObjectMetadata;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author: yingjf
 * @date: 2023/3/9 19:35
 * @description:
 */
@Component("proOssHelper")
public class ProOssHelper {

    private static final Logger LOG = LoggerFactory.getLogger(ProOssHelper.class);

    @Resource
    private ProBaseConfig proBaseConfig;

    /**
     * 内网endPoint
     */
    private String internalEndpointSimple;
    /**
     * 外网
     */
    private String endpointSimple;

    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String runEnvName;
    /**
     * 正式项目名称
     */
    private static final String XBB_DINGTALK = "xbbDingtalk";

    static ClientConfiguration conf = new ClientConfiguration();

    static {
        conf.setConnectionTimeout(10000);
        conf.setSocketTimeout(10000);
        conf.setMaxErrorRetry(0);
    }
    /**
     * 请求客户端
     */
    private OSSClient ossClient;

    @PostConstruct
    private void initFields() {
        internalEndpointSimple = proBaseConfig.getInternalEndpointSimple();
        endpointSimple = proBaseConfig.getEndpointSimple();
        accessKeyId = proBaseConfig.getOssAccessKeyId();
        accessKeySecret = proBaseConfig.getAccessKeySecret();
        accessKeySecret = proBaseConfig.getAccessKeySecret();
        bucketName = proBaseConfig.getBucketName();
        runEnvName = ProBaseConfig.getProjectName();

        String localEnvName = "xbbProLocal";
        //不是本地都用内网
        if (localEnvName.equals(runEnvName)) {
            internalEndpointSimple = endpointSimple;
        }

        /*
         * 一定要在endpoint判断之后
         */
        ossClient = new OSSClient(internalEndpointSimple, accessKeyId, accessKeySecret, conf);
    }


    public void putObject(byte[] buffer, String firstKey) {
        InputStream is = new ByteArrayInputStream(buffer);
        ossClient.putObject(bucketName, firstKey, is);
        LOG.info("Object：" + firstKey + "存入OSS成功。");
    }

    /**
     * 上传InputStream流
     *
     * @param is  InputStream
     * @param key 文件名
     * @return 创建时间： 2018年5月9日 下午7:49:58
     * 修改时间： 2018年5月9日 下午7:49:58 梁鲁江
     * @author 梁鲁江
     */
    public String putObjectInputStream(InputStream is, String key) {
        if (!XBB_DINGTALK.equals(runEnvName)) {
            key = runEnvName + "/" + key;
        }
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType("application/vnd.ms-excel");
        metadata.setContentEncoding("UTF-8");
        LOG.warn("https://" + bucketName + "." + endpointSimple + "/" + key);
        try {
            ossClient.putObject(bucketName, key, is, metadata);
        } catch (Exception e) {
            LOG.error("=======OSS upload failure", e);
        }
        String url = "https://" + bucketName + "." + endpointSimple + "/" + key;
        LOG.info(String.format("（%s）存入OSS成功============（%s）", DateTimeUtil.getString(DateTimeUtil.getDate()) ,url));
        return url;
    }

    /**
     * 上传HSSFWorkbook
     *
     * @param wb  HSSFWorkbook
     * @param key 路径+名称
     * @throws IOException 创建时间： 2018年5月9日 下午7:51:35
     *                     修改时间： 2018年5月9日 下午7:51:35 梁鲁江
     * @author 梁鲁江
     */
    public String putObjectHSSFWorkbook(HSSFWorkbook wb, String key) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        wb.write(baos);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray());
        return putObjectInputStream(byteArrayInputStream, key);
    }

    /**
     * 上传Workbook
     *
     * @param wb  Workbook
     * @param key 路径+名称
     * @throws IOException 创建时间： 2018年5月9日 下午7:52:39
     *                     修改时间： 2018年5月9日 下午7:52:39 梁鲁江
     * @author 梁鲁江
     */
    public String putObjectWorkbook(Workbook wb, String key) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        wb.write(baos);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray());
        String s;
        try {
            s = putObjectInputStream(byteArrayInputStream, key);
        } catch (Exception e) {
            throw e;
        } finally {
            baos.close();
            byteArrayInputStream.close();
        }
        return s;
    }

    /**
     * 根据前缀获取列表
     *
     * @param keyPrefix 前缀名称
     * @throws IOException 创建时间： 2018年4月28日 上午11:03:30
     *                     修改时间： 2018年4月28日 上午11:03:30 梁鲁江
     * @author 梁鲁江
     */
    public List<OSSObjectSummary> listWithPrefix(String keyPrefix) throws IOException {
        // Gets the object with specified prefix. By default it returns up to 100 entries.
        if (!XBB_DINGTALK.equals(runEnvName)) {
            keyPrefix = runEnvName + "/" + keyPrefix;
        }
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix(keyPrefix));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        return sums;
    }

    /**
     * 根据前缀获取列表数量
     *
     * @param keyPrefix 前缀名称
     * @throws IOException 创建时间： 2018年4月28日 上午11:03:30
     *                     修改时间： 2018年4月28日 上午11:03:30 梁鲁江
     * @author 梁鲁江
     */
    public int getListWithPrefixSize(String keyPrefix) throws IOException {
        List<OSSObjectSummary> sums = listWithPrefix(keyPrefix);
        //sums有初始化，默认不会为null
        if (sums != null) {
            return sums.size();
        } else {
            return 0;
        }
    }

    /**
     * Description: 根据oss的文件名获取文件
     * @param key
     * @return java.io.InputStream
     * @throws
     * @author 魏荣杰
     * @date 2022/12/2 11:16
     * @since
     */
    public InputStream getObjectInputStream(String key) {
        OSSObject ossObject = ossClient.getObject(bucketName, key);
        return ossObject.getObjectContent();
    }


}
